package fe.bmsearch.gui.client;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.ResizeComposite;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HTMLTable.Cell;

public class ResultList extends ResizeComposite implements SearchResultListener {

    private static ResultListUiBinder uiBinder = GWT
            .create(ResultListUiBinder.class);

    interface ResultListUiBinder extends UiBinder<Widget, ResultList> {
    }

    interface SelectionStyle extends CssResource {

        String selectedRow();
    }
    private List<SelectedDocumentListener> listeners = new ArrayList<SelectedDocumentListener>();
    private int startIndex, selectedRow = -1;
    private List<SearchResultItem> results;
    static final int VISIBLE_DOCUMENT_COUNT = 20;
    @UiField
    FlexTable header;
    @UiField
    FlexTable table;
    @UiField
    SelectionStyle selectionStyle;

    public ResultList() {
        results = new ArrayList<SearchResultItem>();
        //results.add(new SearchResultItem("Email", "", ""));
        //results.add(new SearchResultItem("Email", "assdfdf", "asddfdf"));

        initWidget(uiBinder.createAndBindUi(this));
        initTable();
        update();
    }

    @Override
    protected void onLoad() {
        // Select the first row if none is selected.
        if (selectedRow == -1 && results.size()>0) {
            selectRow(0);
        }
    }

    @UiHandler("table")
    void onTableClicked(ClickEvent event) {
        // Select the row that was clicked (-1 to account for header row).
        Cell cell = table.getCellForEvent(event);
        if (cell != null) {
            int row = cell.getRowIndex();
            selectRow(row);
        }
    }

    /**
     * Initializes the table so that it contains enough rows for a full page of
     * emails. Also creates the images that will be used as 'read' flags.
     */
    private void initTable() {
        // Initialize the header.

        header.getColumnFormatter().setWidth(1, "296px");


        header.setText(0, 0, "Headline");
        header.setText(0, 1, "Uid");
        //header.getCellFormatter().setHorizontalAlignment(0, 3, HasHorizontalAlignment.ALIGN_RIGHT);

        // Initialize the table.
        table.getColumnFormatter().setWidth(1, "296px");
    }

    /**
     * Selects the given row (relative to the current page).
     *
     * @param row the row to be selected
     */
    private void selectRow(int row) {
        // When a row (other than the first one, which is used as a header) is
        // selected, display its associated MailItem.
        SearchResultItem item = results.get(startIndex + row);
        if (item == null) {
            return;
        }

        styleRow(selectedRow, false);
        styleRow(row, true);

        selectedRow = row;

        for (SelectedDocumentListener l : this.listeners) {
            l.onSelectedDocument(item.documentType, item.uid);
        }
    }

    private void styleRow(int row, boolean selected) {
        if (row != -1) {
            String style = selectionStyle.selectedRow();

            if (selected) {
                table.getRowFormatter().addStyleName(row, style);
            } else {
                table.getRowFormatter().removeStyleName(row, style);
            }
        }
    }

    private void update() {
        // Update the older/newer buttons & label.
        int count = results.size();
        int max = startIndex + VISIBLE_DOCUMENT_COUNT;
        if (max > count) {
            max = count;
        }


        // Show the selected emails.
        int i = 0;
        for (; i < VISIBLE_DOCUMENT_COUNT; ++i) {
            // Don't read past the end.
            if (startIndex + i >= results.size()) {
                break;
            }

            SearchResultItem item = results.get(startIndex + i);

            // Add a new row to the table, then set each of its columns to the
            // email's sender and subject values.
            table.setText(i, 0, item.headline);
            table.setText(i, 1, item.uid);

        }

        // Clear any remaining slots.
        for (; i < Math.min(VISIBLE_DOCUMENT_COUNT, results.size()); ++i) {
            table.removeRow(table.getRowCount() - 1);
        }
    }

    public void setResult(List<SearchResultItem> result) {
        this.results = result;
        update();

    }

    @Override
    public void onSearchResult(List<SearchResultItem> results) {
        this.setResult(results);

    }

    public void addSelectedDocumentListener(SelectedDocumentListener l) {
        this.listeners.add(l);
    }
}
